package com.gitee.wsl.prism4j.languages

import com.gitee.wsl.prism4j.Prism4j
import com.gitee.wsl.prism4j.Prism4j.Companion.grammar
import com.gitee.wsl.prism4j.Prism4j.Companion.pattern
import com.gitee.wsl.prism4j.Prism4j.Companion.token
import com.gitee.wsl.prism4j.Prism4j.Pattern

@Suppress("unused")
object Prism_latex {
    fun create(prism4j: Prism4j): Prism4j.Grammar {
        val funcPattern = Pattern.compile("\\\\(?:[^a-z()\\[\\]]|[a-z*]+)", Pattern.CASE_INSENSITIVE)

        val insideEqu: Prism4j.Grammar? = grammar(
            "inside",
            token("equation-command", pattern(funcPattern, false, false, "regex"))
        )

        return grammar(
            "latex",
            token("comment", pattern(Pattern.compile("%.*", Pattern.MULTILINE))),
            token(
                "cdata",
                pattern(
                    Pattern.compile("(\\\\begin\\{((?:verbatim|lstlisting)\\*?)\\})[\\s\\S]*?(?=\\\\end\\{\\2\\})"),
                    true
                )
            ),
            token(
                "equation",
                pattern(
                    Pattern.compile("\\$(?:\\\\[\\s\\S]|[^\\\\$])*\\$|\\\\\\([\\s\\S]*?\\\\\\)|\\\\\\[[\\s\\S]*?\\\\\\]"),
                    false,
                    false,
                    "string",
                    insideEqu
                ),
                pattern(
                    Pattern.compile("(\\\\begin\\{((?:equation|math|eqnarray|align|multline|gather)\\*?)\\})[\\s\\S]*?(?=\\\\end\\{\\2\\})"),
                    true,
                    false,
                    "string",
                    insideEqu
                )
            ),
            token(
                "keyword",
                pattern(
                    Pattern.compile("(\\\\(?:begin|end|ref|cite|label|usepackage|documentclass)(?:\\[[^\\]]+\\])?\\{)[^}]+(?=\\})"),
                    true
                )
            ),
            token("url", pattern(Pattern.compile("(\\\\url\\{)[^}]+(?=\\})"), true)),
            token(
                "headline", pattern(
                    Pattern.compile("(\\\\(?:part|chapter|section|subsection|frametitle|subsubsection|paragraph|subparagraph|subsubparagraph|subsubsubparagraph)\\*?(?:\\[[^\\]]+\\])?\\{)[^}]+(?=\\}(?:\\[[^\\]]+\\])?)"),
                    true,
                    false,
                    "class-name"
                )
            ),
            token(
                "function", pattern(
                    funcPattern,
                    false,
                    false,
                    "selector"
                )
            ),
            token("punctuation", pattern(Pattern.compile("[\\[\\]{}&]")))
        )
    }
}
